package com.site.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.ProxyHost;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.HeadMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.httpclient.util.URIUtil;
import org.apache.commons.lang.StringUtils;

import com.cnc.bas.util.Log;

public class HttpUtil {

	private static Log log = Log.getLogger(HttpUtil.class);
	public static final String REQUEST_FAILURE = "fail";
	
	/**
	 * 获取请求头信息
	 * @param url
	 * @param headField		请求头字段
	 * @return
	 */
	public static String doHead(String url,String headField){
		HttpClient httpClient=new HttpClient();
		HeadMethod headMethod=new HeadMethod(url);
		try {
			int retCode=httpClient.executeMethod(headMethod);
			if(retCode==200){
				String content=headMethod.getResponseHeader(headField).getValue();
				return content;
			}else if((retCode == HttpStatus.SC_MOVED_TEMPORARILY) ||   
					(retCode == HttpStatus.SC_MOVED_PERMANENTLY) ||   
				    (retCode == HttpStatus.SC_SEE_OTHER) ||   
				     (retCode == HttpStatus.SC_TEMPORARY_REDIRECT)  ){
				Header header = headMethod.getResponseHeader("location");   
				  
			    if (header != null)   
			    {   			  
			        String newuri = header.getValue();   
			  
			        if ((newuri == null) || (newuri.equals(""))) 			  
			            newuri = "/";
			        return doHead(newuri,headField);
			  
			    } else  
			  
			         log.logError("Invalid redirect");   
			    	 return null;
			   }   


		} catch(Exception e){
			log.logError("doHead exception:" + e.getMessage(), e);
		}finally{
			if(null!=headMethod){
				try{
					headMethod.releaseConnection();
				}
				catch(Exception e){
				}
			}
		}
		return null;
	}
	
	/**
	 * 发送get请求
	 * @param url
	 * @param queryObject
	 * @return
	 */
	public static String doGet(String url, Object queryObject) {
		return doGet(url, queryObject, null, null, null, 0);
	}
	
	/**
	 * 发送get请求
	 * @param url
	 * @param queryObject
	 * @return
	 */
	public static String doGet(String url, Object queryObject, String proxyIp, int proxyPort) {
		return doGet(url, queryObject, null, null, proxyIp, proxyPort);
	}
	
	
	public static boolean sendCmd(String targeturl ,String cmds) {
		
		HttpURLConnection connection = null;
		boolean flag = true;
		try {
			URL url = new URL(targeturl);
			connection = (HttpURLConnection) url.openConnection();// 新建连接实例
			connection.setDoOutput(true);// 是否打开输出流 true|false
			connection.setDoInput(true);// 是否打开输入流true|false
			connection.setRequestMethod("POST");// 提交方法POST|GET
			connection.setUseCaches(false);// 是否缓存true|false
		
			connection.connect();// 打开连接端口

			OutputStream  out = connection.getOutputStream();// 打开输出流往对端服务器写数据
			byte[]cmdsbyte = cmds.getBytes("utf-8");
			
			out.write(cmdsbyte);// 写数据,也就是提交你的表单 name=xxx&pwd=xxx
			out.flush();// 刷新
			out.close();// 关闭输出流

			BufferedReader reader = new BufferedReader(new InputStreamReader(
					connection.getInputStream(), "utf-8"));// 往对端写完数据 对端服务器返回数据
															// ,以BufferedReader流来读取
			StringBuffer buffer = new StringBuffer();
			String line = "";
			while ((line = reader.readLine()) != null) {
				buffer.append(line);
			}
			reader.close();
			return flag;
		} catch (IOException e) {
			flag = false;
		} finally {
			if (connection != null) {
				connection.disconnect();// 关闭连接
			}
		}
		return flag;

	}
	 
	/**
	 * 发送post请求
	 * @param url
	 * @param queryObject
	 * @return
	 */
	public static String doPost(String url, Object queryObject) {
		return doPost(url, queryObject, null, null);
	}
	
	
	/**
     * 需要权限校验的get请求
     * @param url
     * @param pairs
     * @param user
     * @param passwd
     * @return
     */
	public static String doGet(String url, Object queryObject, final String user, final String passwd, String proxyIp, int proxyPort) {
        //构造HttpClient的实例
        HttpClient httpClient = new HttpClient();
        httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(30 * 1000);
		httpClient.getHttpConnectionManager().getParams().setSoTimeout(60 * 1000);
        GetMethod getMethod = null;     
        
        if(!StringUtils.isEmpty(proxyIp)){
        	// 使用代理
        	httpClient.getHostConfiguration().setProxy(proxyIp,proxyPort);	
        }
        
        
        try {
            //创建GET方法的实例            
            getMethod = new GetMethod(url); 
            
            getMethod.addRequestHeader("Content-Type", "text/html;charset=UTF-8");
            getMethod.addRequestHeader("Connection", "close");
            
            if(!StringUtils.isEmpty(user)){
            	URL getUrl = new URL(url);
                Credentials defaultcreds = new UsernamePasswordCredentials(user, passwd);
                httpClient.getState().setCredentials(new AuthScope(getUrl.getHost(), getUrl.getPort(), AuthScope.ANY_REALM), defaultcreds);
            }
            
            if (queryObject != null){
				if(queryObject instanceof NameValuePair[]){
					NameValuePair[] pairs = (NameValuePair[])queryObject;
					getMethod.setQueryString(pairs);
				}
				else if(queryObject instanceof String){
					String queryString = (String)queryObject;
					getMethod.setQueryString(URIUtil.encodeQuery(queryString));
				}
				else{
					throw new RuntimeException("unknow queryObject type:" + queryObject.getClass().getName());
				}
			}

            //使用系统提供的默认的恢复策略
            getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
                    new DefaultHttpMethodRetryHandler());

            //执行getMethod
            int statusCode = httpClient.executeMethod(getMethod);
            if (statusCode != HttpStatus.SC_OK) {
                log.logError("url:" + url + " http get failure, status:" + getMethod.getStatusLine());
                return REQUEST_FAILURE;
            }
            
            //读取响应结果
            InputStream is = getMethod.getResponseBodyAsStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            
            String line;
            StringBuffer response = new StringBuffer();
            while((line = br.readLine()) != null){
                response.append(line);
            }
            
            log.logInfo("url:" + url + "do http get result:" + response);
            return response.toString();
        } catch (Exception e){
            log.logError("url:" + url + " get exception:" + e.getMessage(), e);
            return REQUEST_FAILURE;
        }
        finally {
            //释放连接
            if(getMethod != null)
                getMethod.releaseConnection();          
        }
    }
	 
	/**
	 * 需要权限校验的post请求
	 * @param url
	 * @param pairs
	 * @param user
	 * @param passwd
	 * @return
	 */
	public static String doPost(String url, Object queryObject, final String user, final String passwd){
        //构造HttpClient的实例
        HttpClient httpClient = new HttpClient();
        
        httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(30 * 1000);
		httpClient.getHttpConnectionManager().getParams().setSoTimeout(60 * 1000);
          
        PostMethod postMethod = new PostMethod(url);
        String contentType = "text/html;charset=UTF-8";
        postMethod.addRequestHeader("Connection", "close");
        
        try{     
            if(!StringUtils.isEmpty(user)){
            	 URL postUrl = new URL(url);
            	Credentials defaultcreds = new UsernamePasswordCredentials(user, passwd);
                httpClient.getState().setCredentials(new AuthScope(postUrl.getHost(), postUrl.getPort(), AuthScope.ANY_REALM), defaultcreds);
            }
            
            if (queryObject != null){
				if(queryObject instanceof NameValuePair[]){
					NameValuePair[] pairs = (NameValuePair[])queryObject;
					postMethod.setRequestBody(pairs);
				}
				else if(queryObject instanceof String){
					String queryString = (String)queryObject;
					postMethod.setRequestEntity(new StringRequestEntity(queryString, contentType, "UTF-8"));
				}
				else{
					throw new RuntimeException("unknow queryObject type:" + queryObject.getClass().getName());
				}
			}
              
            
            int statusCode = httpClient.executeMethod(postMethod);
            log.logInfo("url:" + url + " http post, return status:" + statusCode);            
            
            InputStream is = postMethod.getResponseBodyAsStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String line;
            StringBuffer response = new StringBuffer();         
            while((line = br.readLine()) != null){
                response.append(line);
            }
            
            log.logInfo("url: " + url + " do http post, result:" + response);

            return response.toString();
        } catch(Exception e){
            log.logError("url:" + url + " do http post exception:" + e.getMessage(), e);
            return REQUEST_FAILURE;
        }
        finally {
            //释放连接
            if(postMethod != null)
                postMethod.releaseConnection();
        }
    }

}
